﻿using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace UnityView
{
    public delegate void OnClick(ButtonView buttonView);

    public class ButtonView : UIView
    {
        public static ColorBlock AppearanceColorBlock = ColorBlock.defaultColorBlock;

        public readonly Button ButtonComponent;

        private UILabel _titleLabel;

        protected UILabel TitleLabel
        {
            get
            {
                if (_titleLabel == null)
                {
                    _titleLabel = new UILabel(this, "Button Text");
                    RectFill(TitleLabel);
                }

                return _titleLabel;
            }
        }

        public Text TitleText
        {
            get { return TitleLabel.TextComponent; }
        }

        public string Title
        {
            set { TitleLabel.Text = value; }
            get { return TitleLabel.Text; }
        }

        [Animatable]
        public Color TitleColor
        {
            set
            {
                if (UIAnimation.OnAnimate())
                {
                    UIAnimation.Append(new TextColorAction(TitleLabel.TextComponent, TitleLabel.TextColor,
                        value));
                }
                else
                {
                    TitleLabel.TextColor = value;
                }
            }
            get { return TitleLabel.TextColor; }
        }

        public override Sprite BackgroundSprite
        {
            set
            {
                ImageComponent.sprite = value;
                ButtonComponent.targetGraphic = ImageComponent;
            }
            get => ImageComponent.sprite;
        }

        public int FontSize
        {
            set { TitleText.fontSize = value; }
            get { return TitleText.fontSize; }
        }

        protected Shadow shadowComponent;

        public Shadow ShadowComponent
        {
            get
            {
                if (shadowComponent == null)
                {
                    shadowComponent = UIObject.AddComponent<Shadow>();
                    shadowComponent.effectDistance = new Vector2(3, -3);
                }
                return shadowComponent;
            }
        }

        public bool ShadowEnable
        {
            set
            {
                ShadowComponent.enabled = value;
            }
            get
            {
                return ShadowComponent.enabled;
            }
        }

        public Vector2 ShadowOffset
        {
            set
            {
                ShadowComponent.effectDistance = value;
            }
            get
            {
                return ShadowComponent.effectDistance;
            }
        }

        public Button.ButtonClickedEvent OnClickListener => ButtonComponent.onClick;

        public void AddListener(UnityAction action)
        {
            OnClickListener.AddListener(action);
        }

        public void Remove()
        {
            OnClickListener.RemoveAllListeners();
        }

        public ButtonView(string name = "Button View") : this(UICanvas.GetInstance(), name)
        {
        }

        public ButtonView(RectTransform transform, string name = "Button View") : base(transform, name)
        {
            ButtonComponent = UIObject.AddComponent<Button>();
            ButtonComponent.colors = AppearanceColorBlock;
        }

        public ButtonView(IViewLayout parent, string name = "Button View") : base(parent, name)
        {
            ButtonComponent = UIObject.AddComponent<Button>();
            ButtonComponent.colors = AppearanceColorBlock;
        }

        public ButtonView(GameObject gameObject) : base(gameObject)
        {
            ButtonComponent = gameObject.GetComponent<Button>() ?? gameObject.AddComponent<Button>();
            ButtonComponent.colors = AppearanceColorBlock;
            var image = gameObject.GetComponent<Image>();
            ImageComponent = image != null ? image : gameObject.AddComponent<Image>();
        }
    }

    public class RadioButtonView : ButtonView, IRadioGroupAction
    {
        public readonly RadioGroup RadioGroup;

        public RadioButtonView(RadioGroup radioGroup, string name = "Radio Button")
            : this(radioGroup, UICanvas.GetInstance(), name)
        {
        }

        public RadioButtonView(RadioGroup radioGroup, IViewLayout parent, string name = "Radio Button")
            : base(parent, name)
        {
            RadioGroup = radioGroup;
            RadioGroup.Add(this);
            AddListener(Active);
        }

        public RadioButtonView(RadioGroup radioGroup, IViewLayout parent, UnityAction action,
            string name = "Radio Button")
            : base(parent, name)
        {
            RadioGroup = radioGroup;
            RadioGroup.Add(this);
            AddListener(action);
        }

        public RadioButtonView(RadioGroup radioGroup, GameObject gameObject) : base(gameObject)
        {
            RadioGroup = radioGroup;
            RadioGroup.Add(this);
            AddListener(Active);
        }

        public Sprite ImageOn { set; get; }
        public Sprite ImageOff { set; get; }
        public string TitleOn { set; get; }
        public string TitleOff { set; get; }

        public void Active()
        {
            RadioGroup.On(this);
        }

        private bool _on = false;
        public void Activate(object sender, bool again)
        {
            if (again) return;
            _on = true;
            if (ImageOn != null) BackgroundSprite = ImageOn;
            if (TitleOn != null) Title = TitleOn;
        }

        public void Deactivate(object sender)
        {
            _on = false;
            if (ImageOn != null) BackgroundSprite = ImageOff;
            if (TitleOn != null) Title = TitleOff;
        }

        public bool On()
        {
            return _on;
        }
    }
}